From: Ben Hutchings Date: Tue, 8 Jan 2013 03:25:52 +0000 (+0000) Subject: radeon: Firmware is required for DRM and KMS on R600 onward X-Git-Tag: archive/raspbian/4.9.82-1+deb9u3+rpi1_jessie~8^2~121 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=3b328a9fa9c7b031bd004f17b5da10aa78fc359d;p=linux-4.9.git radeon: Firmware is required for DRM and KMS on R600 onward radeon requires firmware/microcode for the GPU in all chips, but for newer chips (apparently R600 'Evergreen' onward) it also expects firmware for the memory controller and other sub-blocks. radeon attempts to gracefully fall back and disable some features if the firmware is not available, but becomes unstable - the framebuffer and/or system memory may be corrupted, or the display may stay black. Therefore, perform a basic check for the existence of /lib/firmware/radeon when a device is probed, and abort if it is missing, except for the pre-R600 case. Gbp-Pq: Topic bugfix/all Gbp-Pq: Name radeon-firmware-is-required-for-drm-and-kms-on-r600-onward.patch --- diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 30bd4a6a9d46..1f92c549b496 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -43,6 +43,8 @@ #include "drm_crtc_helper.h" #include "radeon_kfd.h" +#include +#include /* * KMS wrapper. @@ -310,6 +312,29 @@ static struct drm_driver kms_driver; bool radeon_device_is_virtual(void); +/* Test that /lib/firmware/radeon is a directory (or symlink to a + * directory). We could try to match the udev search path, but let's + * assume people take the easy route and install + * firmware-linux-nonfree. + */ +static bool radeon_firmware_installed(void) +{ +#if IS_BUILTIN(CONFIG_DRM_RADEON) + /* It may be too early to tell. Assume it's there. */ + return true; +#else + struct path path; + + if (kern_path("/lib/firmware/radeon", LOOKUP_DIRECTORY | LOOKUP_FOLLOW, + &path) == 0) { + path_put(&path); + return true; + } + + return false; +#endif +} + static int radeon_kick_out_firmware_fb(struct pci_dev *pdev) { struct apertures_struct *ap; @@ -347,6 +372,12 @@ static int radeon_pci_probe(struct pci_dev *pdev, if (vga_switcheroo_client_probe_defer(pdev)) return -EPROBE_DEFER; + if ((ent->driver_data & RADEON_FAMILY_MASK) >= CHIP_R600 && + !radeon_firmware_installed()) { + DRM_ERROR("radeon kernel modesetting for R600 or later requires firmware-amd-graphics.\n"); + return -ENODEV; + } + /* Get rid of things like offb */ ret = radeon_kick_out_firmware_fb(pdev); if (ret)